package org.jeecg.modules.demo.admin.controller;

import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModelProperty;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.modules.demo.admin.entity.dto.PaperPutDTO;
import org.jeecg.modules.demo.admin.service.AdminService;
import org.jeecg.modules.demo.constant.BaseContext;
import org.jeecg.modules.demo.constant.papersStatus;
import org.jeecg.modules.demo.drfAdmin.entity.DrfAdmin;
import org.jeecg.modules.demo.drfAdmin.service.IDrfAdminService;
import org.jeecg.modules.demo.drfFile.domain.DrfFile;
import org.jeecg.modules.demo.drfFile.service.DrfFileService;
import org.jeecg.modules.demo.drfNotice.entity.DrfNotice;
import org.jeecg.modules.demo.drfNotice.service.IDrfNoticeService;
import org.jeecg.modules.demo.drfProblem.entity.DrfProblem;
import org.jeecg.modules.demo.drfProblem.service.IDrfProblemService;
import org.jeecg.modules.demo.drfReviewAssignments.entity.DrfReviewAssignments;
import org.jeecg.modules.demo.drfReviewAssignments.service.IDrfReviewAssignmentsService;
import org.jeecg.modules.demo.drfTecher.entity.DrfTeacher;
import org.jeecg.modules.demo.drfpapers.entity.DrfPapers;
import org.jeecg.modules.demo.drfpapers.service.IDrfPapersService;
import org.jeecg.modules.demo.drfusers.entity.DrfUsers;
import org.jeecg.modules.demo.drfusers.service.IDrfUsersService;
import org.jeecg.modules.demo.pojo.*;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/drf/adminPortal")
@Slf4j
@Api(tags = "盲审—管理端")
public class AdminController {

    //审核时限（一周）
    public static final int time = 7 * 24 * 60 * 60 * 1000;
    @Autowired
    private AdminService adminService;

    @Autowired
    private IDrfUsersService drfUsersService;
    @Autowired
    private IDrfNoticeService drfNoticeService;
    @Autowired
    private IDrfProblemService drfProblemService;
    @Autowired
    private DrfFileService drfFileService;
    @Autowired
    private IDrfPapersService drfPapersService;
    @Autowired
    private IDrfReviewAssignmentsService drfReviewAssignmentsService;
    @Autowired
    private IDrfAdminService drfAdminService;


    final int MAX_PIN = 99;//最大的置顶数

    /**
     * 添加管理员信息
     */
    @ApiOperation("添加(修改)教师信息")
    @GetMapping("/addAdmin")
    public Result<String> addAdmin(adminDTO admin) {
        String userId = String.valueOf(BaseContext.getCurrentId());
        DrfUsers drfUsers = drfUsersService.getById(userId);
        if (!drfUsers.getStatus().equals("admin")) {
            return Result.error("请先登录管理员账号");
        }
        DrfAdmin drfAdmin = new DrfAdmin();
        BeanUtils.copyProperties(admin, drfAdmin);
        drfAdmin.setUserId(userId);
        drfAdminService.updateById(drfAdmin);
        if(admin.getPhone() != null){
           drfUsers.setPhone(admin.getPhone());
            drfUsers.setUpdatedTime(DateTime.now());
            drfUsersService.updateById(drfUsers);
        }
        return Result.success("添加(修改)成功");
    }


    /**
     * 分页列表查询所有论文，并获取推送时间等
     */
    @ApiOperation("分页列表查询所有论文，并获取推送时间等")
    @GetMapping("/listPaper")
    public Result<Page<paperAdminVO>> listPaper(DrfPapers drfPapers,
                                                @RequestParam("pageNo") Integer pageNo,
                                                @RequestParam("pageSize") Integer pageSize,
                                                HttpServletRequest req){
        log.info("分页列表查询所有论文，并获取推送时间等");
        QueryWrapper<DrfPapers> queryWrapper = QueryGenerator.initQueryWrapper(drfPapers, req.getParameterMap());
        Page<DrfPapers> page = new Page<>(pageNo, pageSize);
        Page<DrfPapers> pageList = drfPapersService.page(page, queryWrapper);

        // 创建新的Page对象用于返回
        Page<paperAdminVO> pageListVO = new Page<>(pageNo, pageSize);
        pageListVO.setTotal(pageList.getTotal()); // 设置总数

        // 收集所有论文ID以进行批量查询
        List<String> paperIds = pageList.getRecords().stream()
                .map(DrfPapers::getId)
                .collect(Collectors.toList());

        // 批量获取所有评审分配信息
        Map<String, List<DrfReviewAssignments>> reviewAssignmentMap;
        if (!paperIds.isEmpty()) {
            List<DrfReviewAssignments> allReviewAssignments = drfReviewAssignmentsService.list(
                    new QueryWrapper<DrfReviewAssignments>().in("paper_id", paperIds)
            );
            reviewAssignmentMap = allReviewAssignments.stream()
                    .collect(Collectors.groupingBy(DrfReviewAssignments::getPaperId));
        } else {
            reviewAssignmentMap = new HashMap<>();
        }

        // 转换数据
        List<paperAdminVO> voList = pageList.getRecords().stream().map(drfPaper -> {
            paperAdminVO paperAdminVO = new paperAdminVO();
            BeanUtils.copyProperties(drfPaper, paperAdminVO);

            List<DrfReviewAssignments> reviewAssignments = reviewAssignmentMap.getOrDefault(drfPaper.getId(), Collections.emptyList());
            if (!reviewAssignments.isEmpty()) {
                paperAdminVO.setPushTimeOne(reviewAssignments.get(0).getStartTime());
                paperAdminVO.setPushTeacherOne(reviewAssignments.get(0).getTeacherId());
                if (reviewAssignments.size() > 1) {
                    paperAdminVO.setPushTimeTwo(reviewAssignments.get(1).getStartTime());
                    paperAdminVO.setPushTeacherTwo(reviewAssignments.get(1).getTeacherId());
                } else {
                    paperAdminVO.setPushTimeTwo(null);
                    paperAdminVO.setPushTeacherTwo(null);
                }
            } else {
                paperAdminVO.setPushTimeOne(null);
                paperAdminVO.setPushTeacherOne(null);
                paperAdminVO.setPushTimeTwo(null);
                paperAdminVO.setPushTeacherTwo(null);
            }
            return paperAdminVO;
        }).collect(Collectors.toList());

        pageListVO.setRecords(voList);
        return Result.success(pageListVO);
    }



    /**
     * 推送论文
     * @param paperPutDTOS
     * @return
     */
    @ApiOperation("推送论文")
    @PostMapping("/putPaper")
    public Result<String> putPaper(@RequestBody PaperPutDTO  paperPutDTOS) {
        adminService.putPaper(paperPutDTOS);
        return Result.success("推送成功");
    }


    /**
     * 管理端，添加公告
     */
    @ApiOperation("添加公告")
    @PostMapping("/addNotice")
    public Result addNotice(@RequestBody DrfNotice drfNotice) {
        log.info("管理端：添加公告");
        drfNotice.setStartTime(new Date());
        if(drfNotice.getPin() > 0){//若pin值大于0，则存入pin值为99 - 表中有pin值的数据个数
            if(drfNoticeService.countPin() >= MAX_PIN){
                return Result.error("最多添加" + MAX_PIN + "条置顶公告！");
            }
            drfNotice.setPin(MAX_PIN - drfNoticeService.countPin());
        }
        drfNoticeService.save(drfNotice);
        return Result.success();
    }

    /**
     * 管理端，分页列表查询获取所有公告
     */
    @ApiOperation("分页列表查询获取所有公告")
    @GetMapping("/listNotice")
    public Result listNotice(DrfNotice drfNotice,
                             @RequestParam("pageNo") Integer pageNo,
                             @RequestParam("pageSize") Integer pageSize,
                             HttpServletRequest req) {
        log.info("管理端：分页列表查询获取所有公告");
        QueryWrapper<DrfNotice> queryWrapper = QueryGenerator.initQueryWrapper(drfNotice, req.getParameterMap());
        Page<DrfNotice> page = new Page<DrfNotice>(pageNo, pageSize);
        Page<DrfNotice> pageList = drfNoticeService.page(page, queryWrapper);
        return Result.success(pageList);

    }

    /**
     * 管理端，分页列表查询所有附件问题
     */
    @ApiOperation("分页列表查询所有附件问题")
    @GetMapping("/listAttachProblem")
    public Result listAttachProblem(DrfProblem drfProblem,
                                    @RequestParam("pageNo") Integer pageNo,
                                    @RequestParam("pageSize") Integer pageSize,
                                    HttpServletRequest req) {
        log.info("管理端：分页列表查询获取所有问题");
        QueryWrapper<DrfProblem> queryWrapper = QueryGenerator.initQueryWrapper(drfProblem, req.getParameterMap());
        Page<DrfProblem> page = new Page<DrfProblem>(pageNo, pageSize);
        Page<DrfProblem> pageList = drfProblemService.page(page, queryWrapper);
        return Result.success(pageList);
    }

    /**
     * 管理端，修改公告
     */
    @ApiOperation("修改公告")
    @PostMapping("/updateNotice")
    public Result updateNotice(@RequestBody DrfNotice drfNotice) {
        log.info("管理端：修改公告");
        if (drfNotice.getPin() > 0){
            if(drfNoticeService.countPin() >= MAX_PIN){
                return Result.error("最多添加" + MAX_PIN + "条置顶公告！");
            }
            drfNotice.setPin(MAX_PIN - drfNoticeService.countPin());
        }
        drfNoticeService.updateById(drfNotice);
        return Result.success();
    }

    /**
     * 管理端，删除公告
     */
    @ApiOperation("删除公告")
    @PostMapping("/deleteNotice")
    public Result deleteNotice(@RequestParam("id") String id) {
        log.info("管理端：删除公告");
        drfNoticeService.removeById(id);
        return Result.success();
    }

    /**
     * 管理端，分页列表查询获取所有问题
     */
    @ApiOperation("分页列表查询获取所有问题")
    @GetMapping("/listProblem")
    public Result listProblem(DrfProblem drfProblem,
                              @RequestParam("pageNo") Integer pageNo,
                              @RequestParam("pageSize") Integer pageSize,
                              HttpServletRequest req) {
        log.info("管理端：分页列表查询获取所有问题");
        QueryWrapper<DrfProblem> queryWrapper = QueryGenerator.initQueryWrapper(drfProblem, req.getParameterMap());
        Page<DrfProblem> page = new Page<DrfProblem>(pageNo, pageSize);
        Page<DrfProblem> pageList = drfProblemService.page(page, queryWrapper);

        return Result.success(pageList);
    }

    /**
     * 批量导入用户
     * 前端只需要上传名为 "file" 的 Excel 文件即可
     */
    @ApiOperation("批量导入用户")
    @PostMapping("/addNewUsers")
    public Result<?> addNewUsers(@RequestParam("file") MultipartFile file) {
        // 1. 校验文件是否为空
        if (file == null || file.isEmpty()) {
            return Result.error("文件不能为空！");
        }

        // 2. 检查文件类型（可选）
        String fileName = file.getOriginalFilename();
        if (fileName != null && !fileName.toLowerCase().endsWith(".xlsx") && !fileName.toLowerCase().endsWith(".xls")) {
            return Result.error("只支持 .xls 或 .xlsx 格式的 Excel 文件！");
        }

        ImportParams params = new ImportParams();
        params.setTitleRows(2);   // 跳过前2行标题（可按需调整）
        params.setHeadRows(1);    // 表头占1行
        params.setNeedSave(true); // 如果需要保存上传的临时文件（一般 false 也可）

        try {
            // 3. 使用 ExcelUtil 将 Excel 转为 List<DrfUsers>
            List<DrfUsers> list = ExcelImportUtil.importExcel(file.getInputStream(), DrfUsers.class, params);

            if (list.isEmpty()) {
                return Result.error("文件中没有有效数据！");
            }

            // 4. 批量保存
            long start = System.currentTimeMillis();
            drfUsersService.saveBatch(list);
            long costTime = System.currentTimeMillis() - start;
            log.info("批量导入 {} 条数据，耗时 {} 毫秒", list.size(), costTime);

            return Result.success("文件导入成功！共导入 " + list.size() + " 条数据。");

        } catch (Exception e) {
            log.error("文件导入失败", e);
            String msg = e.getMessage();

            // 判断是否为唯一键冲突（如手机号、身份证重复）
            if (msg != null && msg.contains("Duplicate entry")) {
                return Result.error("导入失败：存在重复数据（唯一键冲突）！");
            } else if (msg != null && msg.contains("Could not parse")) {
                return Result.error("导入失败：日期格式错误，请检查时间字段格式！");
            } else {
                return Result.error("导入失败：" + e.getMessage());
            }
        } finally {
            try {
                file.getInputStream().close(); // 关闭流
            } catch (IOException e) {
                log.warn("关闭文件流失败", e);
            }
        }
    }

    /**
     * 附件问题反馈
     */
    //问题DTO与问题表，
    //DTO，文件表id，文件名，文件问题
    //表，文件表id，文件名，文件问题，日期,论文名，教师名
    @Transactional
    @ApiOperation("附件问题反馈")
    @PostMapping("/fileProblem")
    public Result<String> fileProblem(@RequestBody problemDTO problemDTO) {
        log.info("管理端：附件问题反馈");
        String userId = String.valueOf(BaseContext.getCurrentId());
        DrfUsers drfUsers = drfUsersService.getById(userId);
        DrfFile drfFile = drfFileService.getById(problemDTO.getFileId());
        if (drfFile == null) {
            return Result.error("文件不存在");
        }
        List<teacherProblem> teacherProblems = problemDTO.getProblems();
        if (teacherProblems == null || teacherProblems.isEmpty()){
            return Result.error("请选择文件并填写问题");
        }
        for (teacherProblem teacherProblem : teacherProblems) {
            DrfPapers drfPapers = drfPapersService.getPaperByFileId(problemDTO.getFileId());//获取论文
            //修改论文状态为驳回
            drfPapers.setStatus("reject");
            drfFileService.updateById(drfFile);
            drfPapersService.updateById(drfPapers);
            DrfProblem drfProblem = new DrfProblem();
            drfProblem.setFileId(problemDTO.getFileId());
            drfProblem.setFileName(teacherProblem.getFileName());
            drfProblem.setFileProblem(teacherProblem.getProblem());
            drfProblem.setDate(new Date());
            drfProblem.setPaperId(drfPapers.getId());
            drfProblem.setPaperName(drfPapers.getTitle());
            drfProblem.setStudentId(drfPapers.getStudentId());
            drfProblem.setUserName(drfUsers.getRealName());
            drfProblem.setKnow(0);
            drfProblemService.save(drfProblem);
        }
        return Result.success("反馈成功");
    }

    /**
     * 管理端，获取教师不接受的论文列表
     */
    @ApiOperation("管理端，获取教师不接受的论文列表")
    @GetMapping("/listNotAcceptPaper")
    public Result listNotAcceptPaper(){
        log.info("管理端：获取教师不接受的论文列表");
        String userId = String.valueOf(BaseContext.getCurrentId());
        List<String> paperIds = drfReviewAssignmentsService.getNotAcceptPaper();
        List<DrfPapers> papers = drfPapersService.listByIds(paperIds);
        return Result.success(papers);
    }

    /**
     * 定时任务，用于检查审核中的论文是否超时
     */
    //每天0点检查
    @Scheduled(cron = "0 0 0 * * ?")
    public void checkPaperTimeout() {
        log.info("管理端：检查论文超时");
        //获取所有审核中的论文
        List<DrfReviewAssignments> assignments =
                drfReviewAssignmentsService.list(new QueryWrapper<DrfReviewAssignments>().eq("status", "reviewing"));
        for (DrfReviewAssignments assignment : assignments) {
            Date now = new Date();
            //若时间过期一周
            if (now.getTime() - assignment.getStartTime().getTime() > time) {
                //修改审核任务状态为过期
                assignment.setStatus("expired");
                drfReviewAssignmentsService.updateById(assignment);
            }
        }
    }

    /**
     * 管理端，获取超时的审核任务
     */
    @ApiOperation("管理端，获取超时的审核任务")
    @GetMapping("/listTimeoutAssignments")
    public Result listTimeoutAssignments() {
        log.info("管理端：获取超时审核任务");
        List<DrfReviewAssignments> assignments =
                drfReviewAssignmentsService.list(new QueryWrapper<DrfReviewAssignments>().eq("status", papersStatus.EXPIRED));
        return Result.success(assignments);
    }

    /**
     * 管理端，根据审核任务id修改审核任务状态与推送时间
     */
    @ApiOperation("管理端，根据审核任务id修改审核任务状态与推送时间")
    @PostMapping("/updateAssignment/{id}")
    public Result updateAssignment(@PathVariable String id){
        log.info("管理端：修改审核任务状态与推送时间");
        DrfReviewAssignments assignment = drfReviewAssignmentsService.getById(id);
        assignment.setStatus(papersStatus.REVIEW);
        assignment.setStartTime(new Date());
        drfReviewAssignmentsService.updateById(assignment);
        return Result.success("修改成功");
    }

    /**
     * 管理端，根据用户id重置密码
     */
    @ApiOperation("管理端，根据用户id重置密码")
    @PostMapping("/resetPassword")
    public Result resetPassword(@RequestParam("ids") List<String> ids) {
        log.info("管理端：重置密码");
        for (String id : ids) {
            log.info("修改用户id密码:{}",id);
            DrfUsers drfUsers = drfUsersService.getById(id);
            if (drfUsers == null) {
                return Result.error("用户不存在");
            }
            drfUsers.setPassword("123456");
            drfUsers.setUpdatedTime( new Date());
            drfUsersService.updateById(drfUsers);
        }
        return Result.success("重置成功");
    }


    //批量修改论文状态
    @ApiOperation("批量修改论文状态")
    @PostMapping("/updatePaperStatus")
    public Result updatePaperStatus(@RequestParam("ids") List<String> ids,String  status) {
        log.info("批量修改论文状态");
        for (String id : ids) {
            log.info("修改论文id状态:{}",id);
            try {
                DrfPapers drfPapers = drfPapersService.getById(id);
                drfPapers.setStatus(status);
                drfPapers.setUpdateTime(new Date());
                drfPapersService.updateById(drfPapers);
            } catch (Exception e) {
                log.error("修改论文:"+ id + "状态失败: "+ e.getMessage());
            }
        }
        return Result.success("修改成功");
    }


}
